/*
 * Android Runner is a multiplayer GPS game fully written by Xurxo Mendez Perez
 * 
 * Copyright (C) 2009 Xurxo Mendez Perez
 *   
 * This file is part of Android Runner.
 * 
 * Android Runner is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * Android Runner is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with Android Runner.  If not, see <http://www.gnu.org/licenses/>.
 */

package es.sonxurxo.gpsgame.client.cv.activity;

import java.util.List;

import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;
import android.location.Location;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.view.Menu;
import android.view.MenuItem;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import es.sonxurxo.gpsgame.client.R;
import es.sonxurxo.gpsgame.client.cv.common.actions.CommonActions;
import es.sonxurxo.gpsgame.client.cv.common.dialogs.CommonDialogs;
import es.sonxurxo.gpsgame.client.cv.util.constants.CustomResultCodes;
import es.sonxurxo.gpsgame.client.model.service.game.HttpGameServiceImpl;
import es.sonxurxo.gpsgame.client.model.service.to.Player;
import es.sonxurxo.gpsgame.client.util.exception.ServerException;

/**
 * 
 * @author "Xurxo Mendez Perez"
 *
 */
public class FindGamesActivity extends Activity{

	public static final int SEARCH_METHOD_CITY = 0;
	public static final int SEARCH_METHOD_THIS_CITY = 1;
	public static final int SEARCH_METHOD_LOCATION = 2;
	
	private static final int LOGOUT_ID = Menu.FIRST;
	private static final int FIND_GAMES_ID = Menu.FIRST + 1;

	private Player player;
	
	private Spinner spinner;
	private TextView chooseView, fromYouView;
	
	private String [] cities;
	private int method;
	private Location currentLocation;
	
	private FindCitiesTask findCitiesTask;
	
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
		setContentView(R.layout.find_games_page);
		getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title_1);
		
		spinner = (Spinner)findViewById(R.id.fg_sp_cities);
		chooseView = (TextView)findViewById(R.id.fg_tv_choose);
		
		method = getIntent().getExtras().getInt("method");
		
		player = (Player)getIntent().getExtras().getSerializable("player");
		
		((TextView)findViewById(R.id.title_right_text)).setText(player.getLogin());
		
		if (method == SEARCH_METHOD_CITY) {
			chooseView.setText(R.string.fg_tv_choose_city);
			
			launchFindCitiesThread();
		}
		else if (method == SEARCH_METHOD_THIS_CITY) {
			doFindGames();
		}
		else if (method == SEARCH_METHOD_LOCATION) {
			currentLocation = (Location)getIntent().getExtras().
				getParcelable("location");
			chooseView.setText(R.string.fg_tv_choose_distance);
			fromYouView = (TextView)findViewById(R.id.fg_tv_from_you);
			fromYouView.setText(R.string.fg_tv_from_here);
			fillSpinnerWithDistances();
		}
	}

	private void launchFindCitiesThread() {
		findCitiesTask = new FindCitiesTask();
		Thread loginThread = new Thread(null, findCitiesTask, "Login");
		loginThread.start();
		showDialog(CommonDialogs.CONNECTING_TO_SERVER_DIALOG_ID);
	}

	private void fillSpinnerWithCities() {

		if (cities.length == 0) {
			setResult(CustomResultCodes.FG_NO_CITIES_RESULT_CODE);
			finish();
		}
		spinner.setEnabled(true);
		ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
		        android.R.layout.simple_spinner_dropdown_item,
		            cities);

		spinner.setAdapter(adapter);
	}

	private void fillSpinnerWithDistances() {
		spinner.setEnabled(true);
		ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this,
				R.array.distances, android.R.layout.simple_spinner_dropdown_item);
		spinner.setAdapter(adapter);
	}
	
	private void doLogout() {
		CommonActions.launchLogoutThread(player.getLogin(), this);
	}
	
	private void doFindGames() {
		Intent i = new Intent(this, ViewGamesActivity.class);
		if (method == SEARCH_METHOD_CITY) {
			int position = spinner.getSelectedItemPosition();
			String city = cities[position];
			i.putExtra("city", city);
		}
		else if (method == SEARCH_METHOD_THIS_CITY) {
			try {
				String city = getIntent().getExtras().getString("city");
				i.putExtra("city", city);
			} catch (Exception e) {
				CommonDialogs.errorMessage = e.getLocalizedMessage();
				showDialog(CommonDialogs.CLIENT_ERROR_DIALOG_ID);
			}
		}
		else if (method == SEARCH_METHOD_LOCATION) {
			int position = spinner.getSelectedItemPosition();
			String distance = (String)spinner.getAdapter().getItem(position);
			i.putExtra("distance", distance);
			i.putExtra("location", currentLocation);
		}
		i.putExtra("player", player);
		startActivityForResult(i, CustomResultCodes.VIEW_GAMES_REQUEST_CODE);
//		finish();
	}
	
	@Override
    protected Dialog onCreateDialog(int id) {
		return CommonDialogs.createDialog(id, this);
    }

	
	@Override
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);
        menu.add(0, LOGOUT_ID,0, R.string.fg_mo_logout).setIcon(R.drawable.logout);
        menu.add(0, FIND_GAMES_ID,0, R.string.fg_mo_find_games).setIcon(R.drawable.find);
        return true;
    }
    
    @Override
    public boolean onMenuItemSelected(int featureId, MenuItem item) {
        switch(item.getItemId()) {
        case LOGOUT_ID:
        	doLogout();
        	break;
        case FIND_GAMES_ID:
        	doFindGames();
        	break;
        }
        
        return super.onMenuItemSelected(featureId, item);
    }

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);

		switch (requestCode) {
		case CustomResultCodes.VIEW_GAMES_REQUEST_CODE:
			switch (resultCode) {
			case RESULT_OK:
				Intent mIntent = new Intent();
				mIntent.putExtras(data.getExtras());
				setResult(RESULT_OK, mIntent);
				finish();
				break;
			case RESULT_CANCELED:
//				mIntent = new Intent();
//				mIntent.putExtras(data.getExtras());
				setResult(RESULT_CANCELED);
				finish();
				break;
			case CustomResultCodes.LOGOUT_RESULT_CODE:
				setResult(CustomResultCodes.LOGOUT_RESULT_CODE);
				finish();
				break;
			case CustomResultCodes.VG_NO_GAMES_RESULT_CODE:
				mIntent = new Intent();
				mIntent.putExtras(data.getExtras());
				setResult(CustomResultCodes.VG_NO_GAMES_RESULT_CODE);
				finish();
				break;
			}
			break;
		}
	}
	
	private class LoginHandler extends Handler {

		public LoginHandler(Looper looper) {
			super(looper);
		}
		
		@Override
		public void handleMessage(Message msg) {
    		dismissDialog(CommonDialogs.CONNECTING_TO_SERVER_DIALOG_ID);
			ServerException sE = 
				(ServerException)msg.getData().getSerializable("ServerException");
			if (sE	!= null) {
				CommonDialogs.errorMessage = sE.getMessage();
				showDialog(CommonDialogs.SERVER_ERROR_DIALOG_ID);
	        	spinner.setEnabled(false);
	        	return;
	        }
        	Exception e = 
	        	(Exception)msg.getData().getSerializable("Exception");
	        	if (e != null) {
	        		CommonDialogs.errorMessage = e.getLocalizedMessage();
		        	showDialog(CommonDialogs.CLIENT_ERROR_DIALOG_ID);
		        	spinner.setEnabled(false);
		        	return;
	        	}
			String [] cities2 = (String [])msg.getData().getSerializable("cities");
			if (cities2 != null) {
				cities = cities2;
				fillSpinnerWithCities();
			}
		}
		
	}
	
	private class FindCitiesTask implements Runnable {
		
		public void run() {
			
			LoginHandler handler = new LoginHandler(Looper.getMainLooper());
			Bundle data = new Bundle();
			Message msg = new Message();
			try {
				HttpGameServiceImpl gameService = 
					new HttpGameServiceImpl();
				List<String> citiesList = 
					gameService.findCitiesWithGames();
				data.putSerializable("cities", citiesList.toArray(new String [0]));
				msg.setData(data);
				handler.sendMessage(msg);
				
			} catch (ServerException e) {
	        	data.putSerializable("ServerException", e);
	        	msg.setData(data);
				handler.sendMessage(msg);
	        } catch (Exception e) {
	        	data.putSerializable("Exception", e);
	        	msg.setData(data);
				handler.sendMessage(msg);
	        }
		}
	}
}
